package com.hlkj.baojin.service.impl;

import com.google.common.collect.Maps;
import com.hlkj.baojin.constant.BaojinConstant;
import com.hlkj.baojin.dao.DutyLogDao;
import com.hlkj.baojin.dao.IDutyDao;
import com.hlkj.baojin.dao.repository.DutyLogRepositoty;
import com.hlkj.baojin.dao.repository.DutyRepository;
import com.hlkj.baojin.entity.Duty;
import com.hlkj.baojin.entity.DutyLog;
import com.hlkj.baojin.entity.dto.DutyDto;
import com.hlkj.baojin.entity.dto.DutyLogSearchDto;
import com.hlkj.baojin.entity.dto.DutySearchDto;
import com.hlkj.baojin.entity.dto.ModelList;
import com.hlkj.baojin.jwt.JwtUser;
import com.hlkj.baojin.service.IDutyService;
import com.hlkj.baojin.service.IUserService;
import com.hlkj.baojin.utils.ErrororUtil;
import com.hlkj.baojin.utils.bean.CopyUtil;
import com.hlkj.baojin.utils.bean.JsonResult;
import com.hlkj.baojin.utils.lang.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author HULIN
 * @created with: baojin
 * @package com.hlkj.baojin.service.impl
 * @description:
 * @date 2019/1/29 13:27
 * @modified By:
 * @Copyright © 2018 HAILIANG Info. Tech Ltd. All rights reserved.
 */
@Service
public class DutyServiceImpl implements IDutyService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IDutyDao dutyDao;
    @Autowired
    private DutyRepository dutyRepository;
    @Autowired
    private DutyLogDao dutyLogDao;
    @Autowired
    private DutyLogRepositoty dutyLogRepositoty;

    @Override
    public void saveDuty(DutyDto dutyDto) {
        JwtUser currentUser = userService.getCurrentUser();
        Duty dutyDaoByMobilePhone = dutyDao.findByMobilePhoneAndDelete(dutyDto.getMobilePhone(), BaojinConstant.IS_NO_DELETE);
        ErrororUtil.isFalseNull(dutyDaoByMobilePhone, "新增值班", "当前手机号已注册");

        Duty duty = new Duty(0, currentUser.getId(), System.currentTimeMillis(), BaojinConstant.IS_NO_DELETE);

        BeanUtils.copyProperties(dutyDto, duty, CopyUtil.getNullPropertyNames(dutyDto));
        try {
            dutyDao.save(duty);
        } catch (Exception e) {
            ErrororUtil.isError("新增值班", "保存失败");
        }
    }

    @Override
    public void updateDuty(DutyDto dutyDto) {

        JwtUser currentUser = userService.getCurrentUser();
        ErrororUtil.isTrue(StringUtils.isBlank(dutyDto.getId()),
                "更新值班",
                "数据异常-请传入id");

        Duty dutyDB = dutyDao.findByIdAndDelete(dutyDto.getId(), BaojinConstant.IS_NO_DELETE);
        ErrororUtil.isTrueNull(dutyDB, "更新值班", "不存在当前值班或已离职无法更新");

        Duty dutyDaoByMobilePhone = dutyDao.findByMobilePhoneAndDelete(dutyDto.getMobilePhone(), BaojinConstant.IS_NO_DELETE);

        ErrororUtil.isTrue(dutyDaoByMobilePhone != null && dutyDaoByMobilePhone.getId() != dutyDto.getId(), "更新值班", "手机号已被使用, 请更换");

        Duty duty = new Duty();
        BeanUtils.copyProperties(dutyDto, duty);
        duty.setUpdateMan(currentUser.getId());
        duty.setUpdateTime(System.currentTimeMillis());
        dutyRepository.updateCompanyNotNull(duty);
    }

    @Override
    public JsonResult findDuty(DutySearchDto dutySearchDto) {

        ModelList<Duty> dutyModelList = dutyRepository.getDuty(dutySearchDto);
        List<Duty> dutyList = dutyModelList.getList();

        List<DutyDto> dutyDtoList = new ArrayList<>();
        for (Duty duty : dutyList) {
            DutyDto dutyDto = new DutyDto();
            BeanUtils.copyProperties(duty, dutyDto);
            dutyDtoList.add(dutyDto);
        }

        Map maps = Maps.newHashMap();
        maps.put("list", dutyDtoList);
        maps.put("count", dutyModelList.getCount());

        return JsonResult.success(maps);
    }

    @Override
    public void deleteDuty(String dutyId) {
        Duty duty = dutyDao.findByIdAndDelete(dutyId, BaojinConstant.IS_NO_DELETE);
        ErrororUtil.isTrueNull(duty, "删除值班", "不存在所删除值班");

        JwtUser currentUser = userService.getCurrentUser();
        Duty dutyDetele = new Duty(dutyId, 0, currentUser.getId(), System.currentTimeMillis(), BaojinConstant.IS_DELETE);

        try {
            dutyRepository.updateCompanyNotNull(dutyDetele);
            dutyLogDao.deleteByDutyName(dutyId);
        } catch (Exception e) {
            ErrororUtil.isError("删除值班", "删除失败");
        }
    }

    @Override
    public void statusDuty(String dutyId) {
        Duty duty = dutyDao.findByIdAndDelete(dutyId, BaojinConstant.IS_NO_DELETE);
        Long dutyStatusChangeTime = duty.getDutyStatusChangeTime();
        ErrororUtil.isTrueNull(duty, "更新值班状态", "不存在所更新值班");
        JwtUser currentUser = userService.getCurrentUser();
        Duty statusDuty = new Duty(dutyId, currentUser.getId(), System.currentTimeMillis(), System.currentTimeMillis());
        if (duty.getDutyStatus().equals(0)) {
            statusDuty.setDutyStatus(1);
        } else if (duty.getDutyStatus().equals(1)) {
            statusDuty.setDutyStatus(0);
            //值班切换为不值班时生成值班记录
            if(System.currentTimeMillis() - dutyStatusChangeTime > 5*60*1000L) {
                dateLogGenerate(dutyId, dutyStatusChangeTime, System.currentTimeMillis());
            }
        }
        dutyRepository.updateCompanyNotNull(statusDuty);
    }

    @Override
    public void dateLogGenerate(String dutyId, Long start, Long end) {

        if (DateUtil.isSameDay(new Date(start), new Date(end))) {
            DutyLog dutyLog = new DutyLog(System.currentTimeMillis());
            dutyLog.setDutyName(dutyId);
            dutyLog.setTime(DateUtil.getOfDayFirst(new Date(start)).getTime());
            dutyLog.setTimeStart(start);
            dutyLog.setTimeEnd(end);
            dutyLogDao.save(dutyLog);
        } else {
            List<Date> dateList = DateUtil.getDatesByTwoDates(new Date(start), new Date(end));

            DutyLog dutyLog1 = new DutyLog(System.currentTimeMillis());
            dutyLog1.setDutyName(dutyId);
            dutyLog1.setTime(DateUtil.getOfDayFirst(new Date(start)).getTime());
            dutyLog1.setTimeStart(start);
            dutyLog1.setTimeEnd(DateUtil.getOfDayLast(dateList.get(0)).getTime());
            dutyLogDao.save(dutyLog1);

            DutyLog dutyLog2 = new DutyLog(System.currentTimeMillis());
            dutyLog2.setDutyName(dutyId);
            dutyLog2.setTime(DateUtil.getOfDayFirst(dateList.get(dateList.size() - 1)).getTime());
            dutyLog2.setTimeStart(DateUtil.getOfDayFirst(dateList.get(dateList.size() - 1)).getTime());
            dutyLog2.setTimeEnd(end);
            dutyLogDao.save(dutyLog2);

            if (dateList.size() > 2) {
                dateList.remove(0);
                dateList.remove(dateList.size() - 1);

                for (Date date : dateList) {
                    DutyLog dutyLog = new DutyLog(System.currentTimeMillis());
                    dutyLog.setDutyName(dutyId);
                    dutyLog.setTime(DateUtil.getOfDayFirst(date).getTime());
                    dutyLog.setTimeStart(DateUtil.getOfDayFirst(date).getTime());
                    dutyLog.setTimeEnd(DateUtil.getOfDayLast(date).getTime());
                    dutyLogDao.save(dutyLog);
                }
            }
        }
    }

    @Override
    public List<DutyLog> getDutyLog(DutyLogSearchDto dutyLogSearchDto) {
        List<String> stringList = new ArrayList<>();
        if (StringUtils.isNotBlank(dutyLogSearchDto.getDutyName())) {
            stringList = dutyDao.findByNameLikeAndDelete(dutyLogSearchDto.getDutyName(), BaojinConstant.IS_NO_DELETE)
                    .stream()
                    .map(Duty::getId)
                    .collect(Collectors.toList());
        }
        List<DutyLog> dutyLogList = dutyLogRepositoty.getDutyLog(dutyLogSearchDto, stringList);
        dutyLogList.forEach(dutyLog -> dutyLog.setDutyName(dutyDao.findByIdAndDelete(dutyLog.getDutyName(), BaojinConstant.IS_NO_DELETE).getName()));
        return dutyLogList;
    }
}
